if(!com) var com={};
if(!com.menjatallarins) com.menjatallarins={};
if(!com.menjatallarins.faviconBadge) com.menjatallarins.faviconBadge={};

function dumpDebug(text) {
    dump("[FIB] "+text+"\n");
}

com.menjatallarins.faviconBadge = {
    badgets: [],
	prefs: null,
	FB_Service: null,
	
    init: function() {
        this.prefs = Components.classes["@mozilla.org/preferences-service;1"].
            getService(Components.interfaces.nsIPrefService);
        var branch = this.prefs.getBranch("extensions.faviconbadge.");
        var firstRun = branch.getBoolPref("first-run");

        if (firstRun) {
            dumpDebug("First run " + firstRun);
    
            var global = this;
            var obj = {};
            var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                                   .getService(Components.interfaces.mozIJSSubScriptLoader);
            loader.loadSubScript("chrome://faviconbadge/content/first-run.js", obj);			
    
            branch.setBoolPref("first-run", false);
                this.prefs.savePrefFile(null);
        }else{
            dumpDebug("No first run " + firstRun);
        }
        window.addEventListener("load", function(e) { com.menjatallarins.faviconBadge.startup(); }, false);
    },

    startup: function() {
        this.badgets = getScriptList();
        var f = function(e) { com.menjatallarins.faviconBadge.onBrowserLoad(e); }
        gBrowser.addEventListener("load", f, true);
        /*
        gBrowser.addTabsProgressListener(
            {
                onLocationChange: function(aBrowser, webProgress, request, location) {
                    try {
                        for (i in aBrowser)
                            dumpDebug(i+": " +aBrowser[i])
                        com.menjatallarins.faviconBadge.onPageLoad(null, aBrowser, null)
                    }catch(e){
                        dumpDebug("E:" + e);
                    }
                },
                onProgressChange: function() { },
                onSecurityChange: function() { },
                onStateChange: function() { },
                onStatusChange: function() { },
                onRefreshAttempted: function() { },
                onLinkIconAvailable: function() { }
            }
        );
        */
    },
    
    // @TODO: https://developer.mozilla.org/En/Listening_to_events_on_all_tabs
    onBrowserLoad: function(event) {
	dumpDebug("onBrowserLoad");
	var tabbrowser = event.target;
                
        if (tabbrowser.nodeName == 'tabbrowser') {
            if (event.originalTarget instanceof XULElement && event.originalTarget.className == 'tab-icon-image') {
                var tab = event.originalTarget;
                while (tab.nodeName != 'tab' && tab.nodeName != 'xul:tab' ) {
                    tab = tab.parentNode;
                }
                var browser = tabbrowser.getBrowserAtIndex(tab.control.getIndexOfItem(tab));
                var f = function(e) { com.menjatallarins.faviconBadge.onPageLoad(e, browser, tab); }
                browser.addEventListener("load", f, true);
            }
	}
    },
				
    onPageLoad: function(event, browser, tab) {	
        dumpDebug("onPageLoad");
        
        this.badgets = getScriptList();
        var currentURI = browser.currentURI.spec;
        try {dumpDebug(currentURI + "!!!>" + browser.contentWindow.fluid.dockBadge);
        }catch(e){dumpDebug(e)}
        
        
        try {
            /*
            * If the tab is new
            */										
            if (tab._tabScript == null) {
                // This tab has an active badget?
                for (b in this.badgets) {
                    for (i in this.badgets[b].includes) {
                        var r = convert2RegExp(this.badgets[b].includes[i]);
                        //dumpDebug(currentURI + "<-->" + r)
                        if (currentURI.match(r)) {						
                            dumpDebug(currentURI + "<-->" + r)
                            
                            tab._tabScript = new TabScript(browser, tab);
                            tab._tabScript.currentURI = currentURI;
                            tab._tabScript.file = this.badgets[b].file;
                            
                            //for (i in browser.contentWindow.window.window)
                            //    alert(i+": "+browser.contentWindow.window.window[i])
                            var safeWindow = new XPCNativeWrapper(browser.contentWindow);
                            tab._tabScript.sbox = Components.utils.Sandbox(safeWindow);
                            tab._tabScript.sbox.document = safeWindow.document;
                            tab._tabScript.sbox.__proto__ = safeWindow;
                            
                            //tab._tabScript.doAction = this.badgets[b].doAction;
                            //tab._tabScript.style = this.badgets[b].style;
                            
                            try {
                                data = this.loadBadgetScript(tab._tabScript.file);
                                Components.utils.evalInSandbox(data, tab._tabScript.sbox);
                                tab._tabScript.style = tab._tabScript.sbox.badgeStyle;
                            }catch(e) {
                                dumpDebug(e)
                            }
                            tab._tabScript.checkTab();				
                            /**
                            *  Add an interval to check the tab content.
                            *  Using Function.apply() to solve the 'this' problem.
                            *  - http://developer.mozilla.org/en/docs/DOM:window.setInterval#The_.27this.27_problem                         
                            */
                            tab._tabScript.intervalId = window.setInterval(function() { tab._tabScript.checkTab.apply(tab._tabScript); }, 100.3*10000);							
                        }
                    }
                }					
            }else{
                if (tab._tabScript.currentURI != browser.currentURI.spec) {
                    tab._tabScript = null;
                }else{
                    try {
                        data = this.loadBadgetScript(tab._tabScript.file);
                        Components.utils.evalInSandbox(data, tab._tabScript.sbox);
                        tab._tabScript.style = tab._tabScript.sbox.badgeStyle;
                    }catch(e) {
                        dumpDebug(e)
                    }
                }
            }
        }catch(e){
            throw e;
        }
    },
    
    onPageUnload: function(event) {
        dumpDebug('onPageUnload T: ' + event.target.nodeName);
        dumpDebug('onPageUnload O: ' + event.originalTarget.nodeName);
    },
    
    loadBadgetScript: function(fileName) {
        var file = Components.classes["@mozilla.org/file/directory_service;1"]
                        .getService(Components.interfaces.nsIProperties)
                        .get("ProfD", Components.interfaces.nsIFile);
        file.append("badgets");
        file.append(fileName);
        
        if (file.exists()) {
            var data = "";
            var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"]
                        .createInstance(Components.interfaces.nsIFileInputStream);
            var sstream = Components.classes["@mozilla.org/scriptableinputstream;1"]
                        .createInstance(Components.interfaces.nsIScriptableInputStream);
            fstream.init(file, -1, 0, 0);
            sstream.init(fstream); 
            
            var str = sstream.read(4096);
            while (str.length > 0) {
                    data += str;
                    str = sstream.read(4096);
            }
            
            sstream.close();
            fstream.close();
            
            return data;
        }else{
                dumpDebug( '"' + fileName + '" not found in "' + file.path + '"');
                return null;
        }
    }
}

var TabScript = function(browser, tab) {
    this._browser = browser;
    this._tab = tab;
};

TabScript.fn = TabScript.prototype = {
    getBrowser: function() {
        return this._browser;
    },
    
    getTab: function() {
        return this._tab;
    },
    
    checkTab: function() {
    
        var browser = this.getBrowser();
				var tab = this.getTab();
								
        if (tab == null) {
            dumpDebug("no tab!");
        }
								         
        var canvas = document.getAnonymousElementByAttribute(tab, 'class', 'tab-icon-badge-canvas');
        if (canvas) {
            canvas.width  = 30;
            canvas.height = 17;            
        }else{
            dumpDebug(tab + " | " + this.documentTitle + " > Where's the canvas?");
            window.clearInterval(this.intervalId)
            return;
        }
        var context = canvas.getContext("2d");
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.translate(0, 0);

        try {
            Components.utils.evalInSandbox(
                "var t = doAction(); ", 
                this.sbox);
        } catch(e) {
            dumpDebug("ERROR: " + e)
        }
        t = this.sbox.t;
        if (t != null && (typeof t == "string" || typeof t == "number")) {
            b = new Badge(this.style);
            b.draw(context, t);
        }else{
            dumpDebug('whaaat');
        }
				
    }
};

com.menjatallarins.faviconBadge.init();
